Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

142
Visualizações
Using promises to change properties, but property is not updating [JavaScript]

Description

I am writing a Discord Bot in NodeJS and am currently experiencing a very odd issue.

What I am wanting to do is to get the result of health via method getHP(), afterwards updating the health property with the setHP() method.

This works for one class, but not for another. So basically, the code is practically the same, but for the other class it does not update the property.

I am calling both the classes their setHP() methods in their constructors.

Code:


// Player.js - This works and displays: { current: 98, max: 98 }

class Player {
  constructor(member, msg) {
    this.member = member
    this.msg = msg
    this.setHP()
  }

  health = {}
  setHP() {
    this.getHP.then(hp => {
      this.health = { current: hp.current, max: hp.current }
    })
  }

  get getHP() {
    return new Promise(async (resolve) => {

      const stats = await this.stats
      resolve(stats.find(stat => stat.id === 'health'))
    })
  } 
  
  get stats() {
    return new Promise(async (resolve) => {
      const result = await DB.query(`select stats from members where member_id = ${this.member.id} `)
      resolve(JSON.parse(result[0][0].stats))
    })
  }

  get difficulty() {
    return new Promise(async (resolve) => {
      const result = await DB.query(`select difficulty from members where member_id = ${this.member.id} `)
      resolve(result[0][0].difficulty)
    })
  }
}

// Enemy.js - Doesn't work and displays: {}

class Enemy {
  constructor(player) {
    this.player = player
    this.setHP()
  }

  hp = {}
  setHP() {
    this.getHP.then(int => {
      this.hp = { current: int, max: int }
    })
  }

  get getHP() {
    return new Promise(async (resolve) => {
      const difficulty = await this.player.difficulty
      const int = Math.floor(this.player.health.current * (difficulty * (Math.random() * 0.10 + 0.95)))
      resolve(int)
    })
  }

// minion_fight.js - Where the classes are used

const Enemy = require("Enemy.js")
const Player = require("Player.js")

module.exports.execute = async (msg) => {
  const player = new Player(msg.member, msg)
  const enemy = new Enemy(player)

  // ...
}
about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

The main issue is that the player instance has a pending promise that will eventually resolve and set the player's health property. But before that happens, the enemy instance is created, and it accesses the above mentioned health property from the given player before it has been set. So this.player.health.current cannot be evaluated.

It is better to:

  • Avoid launching asynchronous tasks in a constructor. Instead create methods that do this.
  • Avoid creating promises with new Promise, when there is already a promise to await. This is an anti-pattern.
  • Don't use getters/setters for asynchronous tasks. Just make them asynchronous methods -- it will make the code easier to understand.
  • Please terminate your statements with a semi-colon. You don't really want to make the interpretation of your code dependent on the automatic semi-colon insertion algorithm.

Here is the suggested correction -- but I didn't test it, so I hope you'll at least get the gist of the proposed changes:

// Player.js

class Player {
  constructor(member, msg) {
    this.member = member;
    this.msg = msg;
  }

  health = {}

  async setHP() {
    const hp = await this.getHP();
    this.health = { current: hp.current, max: hp.current };
    return this.health;
  }

  async getHP() {
    const stats = await this.stats();
    return stats.find(stat => stat.id === 'health');
  } 
  
  async stats() {
    const result = await DB.query(`select stats from members where member_id = ${this.member.id} `);
    return JSON.parse(result[0][0].stats);
  }

  async difficulty() {
    const result = await DB.query(`select difficulty from members where member_id = ${this.member.id} `);
    return result[0][0].difficulty;
  }
}

// Enemy.js

class Enemy {
  constructor(player) {
    this.player = player;
  }

  hp = {}
  
  async setHP() {
    const current = await this.getHP();
    this.hp = { current, max: int };
    return this.hp;
  }

  async getHP() {
    const playerHealth = await this.player.getHP(); // To be sure the promise is resolved!
    const difficulty = await this.player.difficulty();
    return Math.floor(playerHealth.current * (difficulty * (Math.random() * 0.10 + 0.95)));
  }
}

// minion_fight.js

const Enemy = require("Enemy.js")
const Player = require("Player.js")

module.exports.execute = async (msg) => {
  const player = new Player(msg.member, msg);
  const enemy = new Enemy(player);
  await enemy.setHP();
  // ...
}
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda